
/**
 * representation of a transporter
 * @author Lukas Koell
 * @author David Medenjak
 * @author Johannes Riedmann
 */
public class Transporter implements Loader, Trailable {

    /** "Anhaengekupplungen" of the transporter */
    protected Hitch[] hitches;
    
    /** departments the animals are put in */
    protected Compartment[] abteile;

    /**
     * Constructor.
     * @param kupplungen number of hitches of the trail
     * @param abteile array of departments of the trail
     */
    public Transporter(int kupplungen, Compartment[] abteile) {
        hitches = new Hitch[kupplungen];
        for (int i = 0; i < kupplungen; i++) {
            hitches[i] = new Hitch();
        }
        this.abteile = abteile;
    }

    /**
     * @return a list of all animals in and on this transporter, including the
     *         anhaenger's
     */
    public String list(String prefix) {
        String ret = "Transporter contains the following: \n";
        ret += prefix + "  - in Departments: \n";
        // iterate over all abteile
        if (abteile != null) {
            for (Compartment abteil : abteile) {
                Animal a = abteil.getAnimal();
                ret += prefix + "  " + abteil.getClass().toString().replace("class ", "") + "\n";
                if (a != null) {
                    ret += prefix + "   * " + a.getName() + "\n";
                } else {
                    ret += "      -- Empty --\n";
                }
            }
        } else {
            ret += prefix + "     * ___nothing___\n";
        }

        // iterate over all couplings
        // and call list() on them. couplings will do the same
        // (hanged animals of course not, they just return their name when called to list() )
        ret += prefix + "  - hanged on: \n";
        for (Hitch h : hitches) {
            if (h == null) {
                continue;
            }
            ITrail l = h.getObject();
            if (l != null) {
                ret += prefix + "   * " + l.list("   ") + "\n";
            }
        }
        return ret;
    }

    @Override
    public boolean load(Animal animal) {
        if (animal.hangOn(this)) {
            return true;
        } else {
            for (Compartment abteil : abteile) {
                if (animal.setCompartment(abteil)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean load(Trail anhaenger) {
        return anhaenger.hangTo(hitches);
    }
    
    @Override
    public Trail unload(int hitchNr) {
        Trail ret = new Trail(hitches.length, abteile);
        hitches[hitchNr].unload();
        return ret;
    }

    /**
     * unloads the compartment
     * @return true if compartment successfully unloaded, else false
     */
    public Animal unload(Compartment compartment) {
        return compartment.unload();
    }
}
